#ifndef QLSDBCONNPOOL_H
#define QLSDBCONNPOOL_H

#include <QString>
#include <QtSql>
#include <QList>
#include <QMutex>

#include "dllQLsDBManager_global.h"

/*
 * 数据库连接池类（单例模式）
 * 单例模式：确保一个类只有一个实例，该类自己进行实例化，并且向整个系统提供这个实例
 */
class DLLQLSDBMANAGER_EXPORT QLsDBConnPool
{
public:
	/* 构造函数 */
	QLsDBConnPool();
	/* 析构函数 */
	~QLsDBConnPool();

	/* 获取数据库连接 */
	static QSqlDatabase getConnection();
	/* 释放数据库连接回连接池 */
	static void releaseConnection(QSqlDatabase connection);
	/* 关闭所有的数据库连接 */
	static void destoryConnectionPool();

	/* select语句 */
	static QSqlRecord* runOne(const QString &content);
	/* insert into语句和update语句 */
	static void runNo(const QString &content);
	/* select语句 */
	static QList<QSqlRecord> runAll(const QString &content);

	/* 获取数据库类型 */
	static QString getType();

private:
	/* 创建数据库连接 */
	QSqlDatabase createConnection(const QString &connectionName);
	/* 单例模式：获取数据库连接池对象 */
	static QLsDBConnPool& getInstance();

private:
	/* 数据库信息 */
	QString m_databaseType;			/* 数据库类型 */
	QString m_hostName;				/* 主机地址 */
	quint32 m_port;					/* 端口号 */
	QString m_databaseName;			/* 数据库名称 */
	QString m_username;				/* 访问账户 */
	QString m_password;				/* 访问密码 */

	/* 连接池配置信息 */
	QString m_type;					/* 数据库类型 */
	bool m_testOnBorrow;			/* 从连接池获取一个连接时，取出是否检测 */
	QString m_testOnBorrowSQL;		/* 取出检测的SQL语句 */
	int m_maxWaitTime;				/* 获取连接最大等待时间 */
	int m_waitInterval;				/* 尝试获取连接时等待间隔时间 */
	int m_maxConnectionCount;		/* 最大连接数 */
	bool m_isSQL;					/* 是否输出sql语句 */

	QList<QString> m_usedConnectionNames;		/* 已使用的数据库连接名 */
	QList<QString> m_unusedConnectionNames;		/* 未使用的数据库连接名 */

	/* 多线程互斥 */
	static QMutex m_instanceMutex;
	static QWaitCondition m_waitConnection;
	/* 唯一一个实例 */
	static QLsDBConnPool *m_instance;
};

#endif // QLSDBCONNPOOL_H
